﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace store.cyt369.com.models.WebRequest
{
    public static class Browser {
        private static bool ValidateCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors)
        {
            if (errors == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }

            return false;
        }

        public static T GetUrl<T>(string url, HttpParameterList parameter = null, HttpHeaderList header = null,
                                                              System.Net.CookieContainer cookieContainer = null,
                                                              System.Text.Encoding encoding = null,
                                                              List<System.Security.Cryptography.X509Certificates.X509Certificate> certificates = null,
                                                              bool allowAutoRedirect = true, bool isGetHeader = false)
        {
            var resp = GetUrl(url, parameter, header, cookieContainer, encoding, certificates, allowAutoRedirect, isGetHeader);
            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                return System.Text.Json.JsonSerializer.Deserialize<T>(resp.ContentString);
            }

            return default(T);
        }
        public static HttpResponse GetUrl(string url, HttpParameterList parameter = null, HttpHeaderList header = null, 
                                                              System.Net.CookieContainer cookieContainer = null, 
                                                              System.Text.Encoding encoding = null, 
                                                              List<System.Security.Cryptography.X509Certificates.X509Certificate> certificates = null,
                                                              bool allowAutoRedirect = true, bool isGetHeader = false) {
            if (parameter != null) {
                foreach (var p in parameter) {
                    url = URLHelper.AddParameter(url, p.Key, p.Value);
                }
            }

            var request = System.Net.HttpWebRequest.Create(url) as System.Net.HttpWebRequest;
            request.CookieContainer = cookieContainer;
            request.AllowAutoRedirect = allowAutoRedirect;
            InitRequestHeaders(request, header);

            return RequestUrl(request, null, "GET", encoding, certificates, true, isGetHeader);
        }

        public static T PostUrl<T>(string url, HttpParameterList parameter, HttpHeaderList header = null,
                                                               System.Net.CookieContainer cookieContainer = null,
                                                               System.Text.Encoding encoding = null,
                                                               List<System.Security.Cryptography.X509Certificates.X509Certificate> certificates = null,
                                                               bool allowAutoRedirect = true, bool isGetHeader = false)
        {
            var resp = PostUrl(url, parameter, header, cookieContainer, encoding, certificates, allowAutoRedirect, isGetHeader);
            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                return System.Text.Json.JsonSerializer.Deserialize<T>(resp.ContentString);
            }

            return default(T);
        }


        public static HttpResponse PostUrl(string url, HttpParameterList parameter, HttpHeaderList header = null, 
                                                               System.Net.CookieContainer cookieContainer = null, 
                                                               System.Text.Encoding encoding = null,
                                                               List<System.Security.Cryptography.X509Certificates.X509Certificate> certificates = null,
                                                               bool allowAutoRedirect = true, bool isGetHeader = false) {
            var request = System.Net.HttpWebRequest.Create(url) as System.Net.HttpWebRequest;
            request.CookieContainer = cookieContainer;
            request.AllowAutoRedirect = allowAutoRedirect;
            InitRequestHeaders(request, header);
            
            return RequestUrl(request, parameter, "POST", encoding, certificates,true, isGetHeader);
        }

        public static HttpResponse RequestUrl(System.Net.HttpWebRequest request, 
                                                                  HttpParameterList parameters, 
                                                                  string method = "GET", 
                                                                  System.Text.Encoding encoding = null, 
                                                                  List<System.Security.Cryptography.X509Certificates.X509Certificate> certificates = null, 
                                                                  bool firstRequest = true, bool isGetHeader = false) {
            HttpResponse retVal = null;

            if (request != null) {
                #region Init
                var now = DateTime.Now;
                byte[] parameterData = null;
                bool isMultipart = false;
                request.KeepAlive = true;
                if (encoding == null) { encoding = System.Text.Encoding.UTF8; }
                request.Method = string.IsNullOrEmpty(method) ? "GET" : method.ToUpper();

                if (string.IsNullOrEmpty(request.Accept)) { request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; }
                if (string.IsNullOrEmpty(request.UserAgent)) { request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.691.400 QQBrowser/9.0.2524.400"; }

                if (request.CachePolicy == null) { request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); }
                if (string.Compare(request.RequestUri.Scheme, "https", true) == 0)
                {
                    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateCertificate);
                }

                if (certificates != null) {//加载客户端证书
                    foreach (var cert in certificates) {
                        request.ClientCertificates.Add(cert);
                    }
                }


                #region ContentType
                if (string.IsNullOrEmpty(request.ContentType)) {
                    if (parameters != null && request.Method == "POST") {
                        if (parameters.HaveStreamParameter) {
                            isMultipart = true;
                            request.ContentType = string.Format("multipart/form-data; boundary=----------{0}", now.Ticks.ToString("x"));
                        } else if(parameters.HaveObjectParameter) {
                            request.ContentType = "application/json";
                        } else {
                            parameterData = encoding.GetBytes(parameters.ToString());
                            if (parameterData.Length > 1024) {
                                isMultipart = true;
                                request.ContentType = string.Format("multipart/form-data; boundary=----------{0}", now.Ticks.ToString("x"));
                            } else {
                                request.ContentType = "application/x-www-form-urlencoded";
                            }
                        }
                    } else {
                        request.ContentType = "application/x-www-form-urlencoded";
                    }
                }
                #endregion

                if (parameters != null && request.Method == "POST") {
                    byte[] boundaryBytes = null;
                    byte[] endBoundaryBytes = null;
                    List<byte[]> parameterByteList = null;
                    Dictionary<byte[], System.IO.Stream> fileParameterByteList = null;

                    #region Disposition
                    if (isMultipart) {
                        request.ContentLength = 0;
                        request.AllowWriteStreamBuffering = false;
                        boundaryBytes = encoding.GetBytes(string.Format("\r\n------------{0}\r\n", now.Ticks.ToString("x")));
                        endBoundaryBytes = encoding.GetBytes(string.Format("\r\n------------{0}--\r\n", now.Ticks.ToString("x")));

                        parameterByteList = new List<byte[]>();
                        fileParameterByteList = new Dictionary<byte[], System.IO.Stream>();
                        foreach (var parameter in parameters) {
                            string contentDisposition = null;
                            if (parameter.IsStream) {
                                contentDisposition = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"; filelength={2}\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\n", parameter.Key, parameter.FileName, parameter.Stream.Length);
                                var bytes = encoding.GetBytes(contentDisposition);
                                request.ContentLength += boundaryBytes.Length + bytes.Length + parameter.Stream.Length;
                                fileParameterByteList.Add(bytes, parameter.Stream);
                            } else {
                                contentDisposition = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\nContent-Type: text/plain; charset=UTF-8\r\nContent-Transfer-Encoding: 8bit\r\n\r\n{1}", parameter.Key, parameter.Value);
                                var bytes = encoding.GetBytes(contentDisposition);
                                request.ContentLength += boundaryBytes.Length + bytes.Length;
                                parameterByteList.Add(bytes);
                            }
                        }

                        request.ContentLength += endBoundaryBytes.Length;
                    }
                    #endregion

                    #region send data
                    var requestStream = request.GetRequestStream();
                    if (isMultipart) {
                        foreach (var data in parameterByteList) {
                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                            requestStream.Write(data, 0, data.Length);
                        }

                        foreach (var item in fileParameterByteList) {
                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                            requestStream.Write(item.Key, 0, item.Key.Length);

                            var data = new byte[1024 * 4];
                            int len = item.Value.Read(data, 0, data.Length);
                            while (len > 0) {
                                requestStream.Write(data, 0, len);
                                len = item.Value.Read(data, 0, data.Length);
                            }
                        }

                        requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                    } else if(parameters.HaveObjectParameter) {
                        if (parameterData == null) {
                            foreach (var p in parameters) {
                                if (p.IsObject) {
                                    if (p.IsJsonString)
                                    {
                                        parameterData = encoding.GetBytes(p.Object as string);
                                    }
                                    else
                                    {
                                        parameterData = encoding.GetBytes(System.Text.Json.JsonSerializer.Serialize(p.Object));
                                    }
                                }
                            }
                        }

                        if (parameterData != null)
                        {
                            requestStream.Write(parameterData, 0, parameterData.Length);
                        }
                    }
                    else {
                        if (parameterData == null) { parameterData = encoding.GetBytes(parameters.ToString()); }
                        requestStream.Write(parameterData, 0, parameterData.Length);
                    }
                    requestStream.Close();
                    #endregion
                }
                #endregion

                try {
                    using (var response = request.GetResponse()) {
                        retVal = new HttpResponse(encoding);
                        var webResponse = response as System.Net.HttpWebResponse;
                        if (webResponse != null) {
                            retVal.StatusCode = webResponse.StatusCode;
                            retVal.Cookies = new HttpCookie(webResponse.Cookies);

                            #region encounter 302 sub request
                            if (webResponse.StatusCode == System.Net.HttpStatusCode.Found) {
                                var path = webResponse.Headers["Location"];
                                Uri uri = null;
                                if (path.IndexOf("http://", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                    path.IndexOf("https://", StringComparison.OrdinalIgnoreCase) >= 0)
                                {
                                    uri = new Uri(path);
                                } else {
                                    uri = new Uri(new Uri(string.Format("{0}://{1}:{2}", request.RequestUri.Scheme, request.RequestUri.Host, request.RequestUri.Port)), path);
                                }
                                var redirectRequest = System.Net.HttpWebRequest.Create(uri) as System.Net.HttpWebRequest;
                                redirectRequest.AllowAutoRedirect = false;
                                redirectRequest.CookieContainer = new System.Net.CookieContainer();
                                foreach (var item in retVal.Cookies) {
                                    redirectRequest.CookieContainer.Add(item.Value);
                                }

                                var resp = RequestUrl(redirectRequest, null, firstRequest: false);
                                if (resp != null) {
                                    if (resp.Cookies != null) {
                                        retVal.Cookies.SetCookie(resp.Cookies);
                                    }

                                    if (resp.Headers != null) {
                                        retVal.Headers.AppendHeaders(resp.Headers);
                                    }

                                    retVal.Stream = resp.Stream;
                                }

                                if (firstRequest) {
                                    response.Close();
                                    request.Abort();
                                    return retVal;
                                }
                            }
                            #endregion
                        }

                        #region content stream
                        var stream = response.GetResponseStream();
                        retVal.Stream = new System.IO.MemoryStream();

                        int bufferLen = 1024 * 4;
                        byte[] buffer = new byte[bufferLen];
                        int resultLen = stream.Read(buffer, 0, bufferLen);

                        while (resultLen > 0) {
                            retVal.Stream.Write(buffer, 0, resultLen);
                            resultLen = stream.Read(buffer, 0, bufferLen);
                        }

                        if (isGetHeader) {
                            retVal.Headers = new HttpResponseHeaderList();
                            foreach (string key in response.Headers.Keys) {
                                retVal.Headers.Add(key, response.Headers[key]);
                            }
                        }

                        response.Close();
                        #endregion
                    }
                } catch (System.Net.WebException ex) {
                    if (ex.Response != null)
                    {
                        #region error content stream
                        var stream = ex.Response.GetResponseStream();
                        retVal = new HttpResponse(encoding);
                        retVal.Stream = new System.IO.MemoryStream();
                        retVal.StatusCode = System.Net.HttpStatusCode.InternalServerError;

                        int bufferLen = 1024 * 4;
                        byte[] buffer = new byte[bufferLen];
                        int resultLen = stream.Read(buffer, 0, bufferLen);

                        while (resultLen > 0)
                        {
                            retVal.Stream.Write(buffer, 0, resultLen);
                            resultLen = stream.Read(buffer, 0, bufferLen);
                        }

                        ex.Response.Close();
                        #endregion
                    }
                    else {
                        throw ex;
                    }
                } finally {
                    request.Abort();
                }
            }

            return retVal;
        }

        private static void InitRequestHeaders(System.Net.HttpWebRequest request, HttpHeaderList header = null) {
            if (request != null && header != null) {
                foreach (var item in header) {
                    switch (item.Key.ToUpper()) {
                        case "CONTENT-TYPE":
                            request.ContentType = item.Value;
                            break;

                        case "REFERER":
                            request.Referer = item.Value;
                            break;

                        case "USER-AGENT":
                            request.UserAgent = item.Value;
                            break;

                        case "ACCEPT":
                            request.Accept = item.Value;
                            break;

                        default:
                            request.Headers.Add(item.Key, item.Value);
                            break;
                    }
                }
            }
        }

        public static string ConvertContentType(string fileExtention) {
            if (!string.IsNullOrEmpty(fileExtention)) {
                #region switch
                switch (fileExtention.ToLower()) {
                    #region 0.001
                    case "0.001":
                        return "application/x-001";
                    case "0.323":
                        return "text/h323";
                    case "0.301":
                        return "application/x-301";
                    case "0.906":
                        return "application/x-906";
                    case "0.907":
                        return "drawing/907";
                    #endregion

                    #region a
                    case ".a11":
                        return "application/x-a11";
                    case ".acp":
                        return "audio/x-mei-aac";
                    case ".ai":
                        return "application/postscript";
                    case ".aif":
                        return "audio/aiff";
                    case ".aifc":
                        return "audio/aiff";
                    case ".aiff":
                        return "audio/aiff";
                    case ".anv":
                        return "application/x-anv";
                    case ".asa":
                        return "text/asa";
                    case ".asf":
                        return "video/x-ms-asf";
                    case ".asp":
                        return "text/asp";
                    case ".asx":
                        return "video/x-ms-asf";
                    case ".au":
                        return "audio/basic";
                    case ".avi":
                        return "video/avi";
                    case ".awf":
                        return "application/vnd.adobe.workflow";
                    case ".apk":
                        return "application/vnd.android.package-archive";
                    #endregion

                    #region b
                    case ".bmp":
                        return "application/x-bmp";
                    case ".bot":
                        return "application/x-bot";
                    #endregion

                    #region c
                    case ".c4t":
                        return "application/x-c4t";
                    case ".c90":
                        return "application/x-c90";
                    case ".cal":
                        return "application/x-cals";
                    case ".cat":
                        return "application/vnd.ms-pki.seccat";
                    case ".cdf":
                        return "application/x-netcdf";
                    case ".cdr":
                        return "application/x-cdr";
                    case ".cel":
                        return "application/x-cel";
                    case ".cer":
                        return "application/x-x509-ca-cert";
                    case ".cg4":
                        return "application/x-g4";
                    case ".cgm":
                        return "application/x-cgm";
                    case ".cit":
                        return "application/x-cit";
                    case ".class":
                        return "application/java";
                    case ".cml":
                        return "text/xml";
                    case ".cmp":
                        return "application/x-cmp";
                    case ".cmx":
                        return "application/x-cmx";
                    case ".cot":
                        return "application/x-cot";
                    case ".crl":
                        return "application/pkix-crl";
                    case ".crt":
                        return "application/x-x509-ca-cert";
                    case ".csi":
                        return "application/x-csi";
                    case ".css":
                        return "text/css";
                    case ".cs":
                        return "text/plain";
                    case ".cut":
                        return "application/x-cut";
                    #endregion

                    #region d
                    case ".dbm":
                        return "application/x-dbm";
                    case ".dbx":
                        return "application/x-dbx";
                    case ".dcd":
                        return "text/xml";
                    case ".dcx":
                        return "application/x-dcx";
                    case ".der":
                        return "application/x-x509-ca-cert";
                    case ".dgn":
                        return "application/x-dgn";
                    case ".dib":
                        return "application/x-dib";
                    case ".dll":
                        return "application/x-msdownload";
                    case ".doc":
                        return "application/msword";
                    case ".dot":
                        return "application/msword";
                    case ".drw":
                        return "application/x-drw";
                    case ".dtd":
                        return "text/xml";
                    case ".dwf":
                        return "application/x-dwf";
                    case ".dwg":
                        return "application/x-dwg";
                    case ".dxb":
                        return "application/x-dxb";
                    case ".dxf":
                        return "application/x-dxf";
                    #endregion

                    #region e
                    case ".edn":
                        return "application/vnd.adobe.edn";
                    case ".emf":
                        return "application/x-emf";
                    case ".eml":
                        return "message/rfc822";
                    case ".ent":
                        return "text/xml";
                    case ".epi":
                        return "application/x-epi";
                    case ".eps":
                        return "application/x-ps";
                    case ".etd":
                        return "application/x-ebx";
                    case ".exe":
                        return "application/x-msdownload";
                    #endregion

                    #region f
                    case ".fax":
                        return "image/fax";
                    case ".fdf":
                        return "application/vnd.fdf";
                    case ".fif":
                        return "application/fractals";
                    case ".fo":
                        return "text/xml";
                    case ".frm":
                        return "application/x-frm";
                    #endregion

                    #region g
                    case ".g4":
                        return "application/x-g4";
                    case ".gbr":
                        return "application/x-gbr";
                    case ".gif":
                        return "image/gif";
                    case ".gl2":
                        return "application/x-gl2";
                    case ".gp4":
                        return "application/x-gp4";
                    #endregion

                    #region h
                    case ".hgl":
                        return "application/x-hgl";
                    case ".hmr":
                        return "application/x-hmr";
                    case ".hpg":
                        return "application/x-hpgl";
                    case ".hpl":
                        return "application/x-hpl";
                    case ".hqx":
                        return "application/mac-binhex40";
                    case ".hrf":
                        return "application/x-hrf";
                    case ".hta":
                        return "application/hta";
                    case ".htc":
                        return "text/x-component";
                    case ".htm":
                        return "text/html";
                    case ".html":
                        return "text/html";
                    case ".htt":
                        return "text/webviewhtml";
                    case ".htx":
                        return "text/html";
                    #endregion

                    #region i
                    case ".icb":
                        return "application/x-icb";
                    case ".ico":
                        return "image/x-icon";
                    case ".iff":
                        return "application/x-iff";
                    case ".ig4":
                        return "application/x-g4";
                    case ".igs":
                        return "application/x-igs";
                    case ".iii":
                        return "application/x-iphone";
                    case ".img":
                        return "application/x-img";
                    case ".ins":
                        return "application/x-internet-signup";
                    case ".isp":
                        return "application/x-internet-signup";
                    case ".ivf":
                        return "video/x-ivf";
                    case ".ipa":
                        return "application/vnd.iphone";
                    #endregion

                    #region j
                    case ".java":
                        return "java/*";
                    case ".jfif":
                        return "image/jpeg";
                    case ".jpe":
                        return "image/jpeg";
                    case ".jpeg":
                        return "image/jpeg";
                    case ".jpg":
                        return "image/jpeg";
                    case ".js":
                        return "application/x-javascript";
                    case ".jsp":
                        return "text/html";
                    #endregion

                    #region l
                    case ".la1":
                        return "audio/x-liquid-file";
                    case ".lar":
                        return "application/x-laplayer-reg";
                    case ".latex":
                        return "application/x-latex";
                    case ".lavs":
                        return "audio/x-liquid-secure";
                    case ".lbm":
                        return "application/x-lbm";
                    case ".lmsff":
                        return "audio/x-la-lms";
                    case ".ls":
                        return "application/x-javascript";
                    case ".ltr":
                        return "application/x-ltr";
                    #endregion

                    #region m
                    case ".m1v":
                        return "video/x-mpeg";
                    case ".m2v":
                        return "video/x-mpeg";
                    case ".m3u":
                        return "audio/mpegurl";
                    case ".m4e":
                        return "video/mpeg4";
                    case ".mac":
                        return "application/x-mac";
                    case ".man":
                        return "application/x-troff-man";
                    case ".math":
                        return "text/xml";
                    case ".mdb":
                        return "application/msaccess";
                    case ".mfp":
                        return "application/x-shockwave-flash";
                    case ".mht":
                        return "message/rfc822";
                    case ".mhtml":
                        return "message/rfc822";
                    case ".mi":
                        return "application/x-mi";
                    case ".mid":
                        return "audio/mid";
                    case ".midi":
                        return "audio/mid";
                    case ".mil":
                        return "application/x-mil";
                    case ".mml":
                        return "text/xml";
                    case ".mnd":
                        return "audio/x-musicnet-download";
                    case ".mns":
                        return "audio/x-musicnet-stream";
                    case ".mocha":
                        return "application/x-javascript";
                    case ".movie":
                        return "video/x-sgi-movie";
                    case ".mp1":
                        return "audio/mp1";
                    case ".mp2":
                        return "audio/mp2";
                    case ".mp2v":
                        return "video/mpeg";
                    case ".mp3":
                        return "audio/mp3";
                    case ".mp4":
                        return "video/mpeg4";
                    case ".mpa":
                        return "video/x-mpg";
                    case ".mpd":
                        return "application/vnd.ms-project";
                    case ".mpe":
                        return "video/x-mpeg";
                    case ".mpeg":
                        return "video/mpg";
                    case ".mpg":
                        return "video/mpg";
                    case ".mpga":
                        return "audio/rn-mpeg";
                    case ".mpp":
                        return "application/vnd.ms-project";
                    case ".mps":
                        return "video/x-mpeg";
                    case ".mpt":
                        return "application/vnd.ms-project";
                    case ".mpv":
                        return "video/mpg";
                    case ".mpv2":
                        return "video/mpeg";
                    case ".mpw":
                        return "application/vnd.ms-project";
                    case ".mpx":
                        return "application/vnd.ms-project";
                    case ".mtx":
                        return "text/xml";
                    case ".mxp":
                        return "application/x-mmxp";
                    #endregion

                    #region n
                    case ".net":
                        return "image/pnetvue";
                    case ".nrf":
                        return "application/x-nrf";
                    case ".nws":
                        return "message/rfc822";
                    #endregion

                    #region o
                    case ".odc":
                        return "text/x-ms-odc";
                    case ".out":
                        return "application/x-out";
                    #endregion

                    #region p
                    case ".p10":
                        return "application/pkcs10";
                    case ".p12":
                        return "application/x-pkcs12";
                    case ".p7b":
                        return "application/x-pkcs7-certificates";
                    case ".p7c":
                        return "application/pkcs7-mime";
                    case ".p7m":
                        return "application/pkcs7-mime";
                    case ".p7r":
                        return "application/x-pkcs7-certreqresp";
                    case ".p7s":
                        return "application/pkcs7-signature";
                    case ".pc5":
                        return "application/x-pc5";
                    case ".pci":
                        return "application/x-pci";
                    case ".pcl":
                        return "application/x-pcl";
                    case ".pcx":
                        return "application/x-pcx";
                    case ".pdf":
                        return "application/pdf";
                    case ".pdx":
                        return "application/vnd.adobe.pdx";
                    case ".pfx":
                        return "application/x-pkcs12";
                    case ".pgl":
                        return "application/x-pgl";
                    case ".pic":
                        return "application/x-pic";
                    case ".pko":
                        return "application/vnd.ms-pki.pko";
                    case ".pl":
                        return "application/x-perl";
                    case ".plg":
                        return "text/html";
                    case ".pls":
                        return "audio/scpls";
                    case ".plt":
                        return "application/x-plt";
                    case ".png":
                        return "image/png";
                    case ".pot":
                        return "application/vnd.ms-powerpoint";
                    case ".ppa":
                        return "application/vnd.ms-powerpoint";
                    case ".ppm":
                        return "application/x-ppm";
                    case ".pps":
                        return "application/vnd.ms-powerpoint";
                    case ".ppt":
                        return "application/vnd.ms-powerpoint";
                    case ".pr":
                        return "application/x-pr";
                    case ".prf":
                        return "application/pics-rules";
                    case ".prn":
                        return "application/x-prn";
                    case ".prt":
                        return "application/x-prt";
                    case ".ps":
                        return "application/x-ps";
                    case ".ptn":
                        return "application/x-ptn";
                    case ".pwz":
                        return "application/vnd.ms-powerpoint";
                    #endregion

                    #region r
                    case ".r3t":
                        return "text/vnd.rn-realtext3d";
                    case ".ra":
                        return "audio/vnd.rn-realaudio";
                    case ".ram":
                        return "audio/x-pn-";
                    case ".ras":
                        return "application/x-ras";
                    case ".rat":
                        return "application/rat-file";
                    case ".rdf":
                        return "text/xml";
                    case ".rec":
                        return "application/vnd.rn-recording";
                    case ".red":
                        return "application/x-red";
                    case ".rgb":
                        return "application/x-rgb";
                    case ".rjs":
                        return "application/vnd.rn-realsystem-rjs";
                    case ".rjt":
                        return "application/vnd.rn-realsystem-rjt";
                    case ".rlc":
                        return "application/x-rlc";
                    case ".rle":
                        return "application/x-rle";
                    case ".rm":
                        return "application/vnd.rn-realmedia";
                    case ".rmf":
                        return "application/vnd.adobe.rmf";
                    case ".rmi":
                        return "audio/mid";
                    case ".rmj":
                        return "application/vnd.rn-realsystem-rmj";
                    case ".rmm":
                        return "audio/x-pn-realaudio";
                    case ".rmp":
                        return "application/vnd.rn-rn_music_package";
                    case ".rms":
                        return "application/vnd.rn-realmedia-secure";
                    case ".rmvb":
                        return "application/vnd.rn-realmedia-vbr";
                    case ".rmx":
                        return "application/vnd.rn-realsystem-rmx";
                    case ".rnx":
                        return "application/vnd.rn-realplayer";
                    case ".rp":
                        return "image/vnd.rn-realpix";
                    case ".rpm":
                        return "audio/x-pn-realaudio-plugin";
                    case ".rsml":
                        return "application/vnd.rn-rsml";
                    case ".rt":
                        return "text/vnd.rn-realtext";
                    case ".rtf":
                        return "application/msword";
                    case ".rv":
                        return "video/vnd.rn-realvideo";
                    #endregion

                    #region s
                    case ".sam":
                        return "application/x-sam";
                    case ".sat":
                        return "application/x-sat";
                    case ".sdp":
                        return "application/sdp";
                    case ".sdw":
                        return "application/x-sdw";
                    case ".sit":
                        return "application/x-stuffit";
                    case ".slb":
                        return "application/x-slb";
                    case ".sld":
                        return "application/x-sld";
                    case ".slk":
                        return "drawing/x-slk";
                    case ".smi":
                        return "application/smil";
                    case ".smil":
                        return "application/smil";
                    case ".smk":
                        return "application/x-smk";
                    case ".snd":
                        return "audio/basic";
                    case ".sol":
                        return "text/plain";
                    case ".sor":
                        return "text/plain";
                    case ".spc":
                        return "application/x-pkcs7-certificates";
                    case ".spl":
                        return "application/futuresplash";
                    case ".spp":
                        return "text/xml";
                    case ".ssm":
                        return "application/streamingmedia";
                    case ".sst":
                        return "application/vnd.ms-pki.certstore";
                    case ".stl":
                        return "application/vnd.ms-pki.stl";
                    case ".stm":
                        return "text/html";
                    case ".sty":
                        return "application/x-sty";
                    case ".svg":
                        return "text/xml";
                    case ".swf":
                        return "application/x-shockwave-flash";
                    case ".sis":
                        return "application/vnd.symbian.install";
                    case ".sisx":
                        return "application/vnd.symbian.install";
                    #endregion

                    #region t
                    case ".tdf":
                        return "application/x-tdf";
                    case ".tg4":
                        return "application/x-tg4";
                    case ".tga":
                        return "application/x-tga";
                    case ".tif":
                        return "image/tiff";
                    case ".tiff":
                        return "image/tiff";
                    case ".tld":
                        return "text/xml";
                    case ".top":
                        return "drawing/x-top";
                    case ".torrent":
                        return "application/x-bittorrent";
                    case ".tsd":
                        return "text/xml";
                    case ".txt":
                        return "text/plain";
                    #endregion

                    #region u
                    case ".uin":
                        return "application/x-icq";
                    case ".uls":
                        return "text/iuls";
                    #endregion

                    #region v
                    case ".vcf":
                        return "text/x-vcard";
                    case ".vda":
                        return "application/x-vda";
                    case ".vdx":
                        return "application/vnd.visio";
                    case ".vml":
                        return "text/xml";
                    case ".vpg":
                        return "application/x-vpeg005";
                    case ".vsd":
                        return "application/vnd.visio";
                    case ".vss":
                        return "application/vnd.visio";
                    case ".vst":
                        return "application/vnd.visio";
                    case ".vsw":
                        return "application/vnd.visio";
                    case ".vsx":
                        return "application/vnd.visio";
                    case ".vtx":
                        return "application/vnd.visio";
                    case ".vxml":
                        return "text/xml";
                    #endregion

                    #region w
                    case ".wav":
                        return "audio/wav";
                    case ".wax":
                        return "audio/x-ms-wax";
                    case ".wb1":
                        return "application/x-wb1";
                    case ".wb2":
                        return "application/x-wb2";
                    case ".wb3":
                        return "application/x-wb3";
                    case ".wbmp":
                        return "image/vnd.wap.wbmp";
                    case ".wiz":
                        return "application/msword";
                    case ".wk3":
                        return "application/x-wk3";
                    case ".wk4":
                        return "application/x-wk4";
                    case ".wkq":
                        return "application/x-wkq";
                    case ".wks":
                        return "application/x-wks";
                    case ".wm":
                        return "video/x-ms-wm";
                    case ".wma":
                        return "audio/x-ms-wma";
                    case ".wmd":
                        return "application/x-ms-wmd";
                    case ".wmf":
                        return "application/x-wmf";
                    case ".wml":
                        return "text/vnd.wap.wml";
                    case ".wmv":
                        return "video/x-ms-wmv";
                    case ".wmx":
                        return "video/x-ms-wmx";
                    case ".wmz":
                        return "application/x-ms-wmz";
                    case ".wp6":
                        return "application/x-wp6";
                    case ".wpd":
                        return "application/x-wpd";
                    case ".wpg":
                        return "application/x-wpg";
                    case ".wpl":
                        return "application/vnd.ms-wpl";
                    case ".wq1":
                        return "application/x-wq1";
                    case ".wr1":
                        return "application/x-wr1";
                    case ".wri":
                        return "application/x-wri";
                    case ".wrk":
                        return "application/x-wrk";
                    case ".ws":
                        return "application/x-ws";
                    case ".ws2":
                        return "application/x-ws";
                    case ".wsc":
                        return "text/scriptlet";
                    case ".wsdl":
                        return "text/xml";
                    case ".wvx":
                        return "video/x-ms-wvx";
                    #endregion

                    #region x
                    case ".xap":
                        return "application/x-silverlight-app";
                    case ".xdp":
                        return "application/vnd.adobe.xdp";
                    case ".xdr":
                        return "text/xml";
                    case ".xfd":
                        return "application/vnd.adobe.xfd";
                    case ".xfdf":
                        return "application/vnd.adobe.xfdf";
                    case ".xhtml":
                        return "text/html";
                    case ".xls":
                        return "application/vnd.ms-excel";
                    case ".xlw":
                        return "application/x-xlw";
                    case ".xml":
                        return "text/xml";
                    case ".xpl":
                        return "audio/scpls";
                    case ".xq":
                        return "text/xml";
                    case ".xql":
                        return "text/xml";
                    case ".xquery":
                        return "text/xml";
                    case ".xsd":
                        return "text/xml";
                    case ".xsl":
                        return "text/xml";
                    case ".xslt":
                        return "text/xml";
                    case ".xwd":
                        return "application/x-xwd";
                    case ".x_b":
                        return "application/x-x_b";
                    case ".x_t":
                        return "application/x-x_t";
                    #endregion

                    #region z
                    case ".zip":
                        return "application/x-zip-compressed";
                    #endregion

                    default:
                        break;
                }
                #endregion
            }
            return "application/octet-stream";
        }
    }
}
